/**
 * 情感化动画效果库
 * 提供各种情感相关的动画效果和交互反馈
 */

/**
 * 动画选项接口
 */
const AnimationOptions = {
  duration: 'number',
  delay: 'number',
  easing: 'string',
  iterations: 'number',
  direction: ['normal', 'reverse', 'alternate', 'alternate-reverse'],
  fillMode: ['none', 'forwards', 'backwards', 'both'],
  timingFunction: 'string'
};

/**
 * 情感动画配置接口
 */
const EmotionAnimationConfig = {
  name: 'string',
  keyframes: 'array',
  options: 'object',
  emotion: 'string',
  intensity: ['low', 'medium', 'high']
};

/**
 * 粒子配置接口
 */
const ParticleConfig = {
  count: 'number',
  size: { min: 'number', max: 'number' },
  speed: { min: 'number', max: 'number' },
  color: 'array',
  shape: ['circle', 'heart', 'star', 'sparkle'],
  lifetime: 'number',
  gravity: 'number',
  wind: 'number'
};

class EmotionAnimations {
  animationInstances = new Map();
  particleSystems = new Map();
  constructor() {
    this.activeAnimations = new Set();
  }

  // 情感动画预设
  emotionAnimations = {
    happy: [
      {
        name: 'bounce-joy',
        keyframes: [
          { transform: 'translateY(0) scale(1)', offset: 0 },
          { transform: 'translateY(-20rpx) scale(1.1)', offset: 0.3 },
          { transform: 'translateY(0) scale(1)', offset: 0.6 },
          { transform: 'translateY(-10rpx) scale(1.05)', offset: 0.8 },
          { transform: 'translateY(0) scale(1)', offset: 1 }
        ],
        options: {
          duration: 800,
          easing: 'cubic-bezier(0.68, -0.55, 0.265, 1.55)',
          iterations: 1
        },
        emotion: 'happy',
        intensity: 'medium'
      },
      {
        name: 'wiggle-happy',
        keyframes: [
          { transform: 'rotate(0deg)', offset: 0 },
          { transform: 'rotate(5deg)', offset: 0.25 },
          { transform: 'rotate(-5deg)', offset: 0.75 },
          { transform: 'rotate(0deg)', offset: 1 }
        ],
        options: {
          duration: 500,
          easing: 'ease-in-out',
          iterations: 3
        },
        emotion: 'happy',
        intensity: 'high'
      },
      {
        name: 'glow-happiness',
        keyframes: [
          { boxShadow: '0 0 0 rgba(255, 217, 61, 0)', offset: 0 },
          { boxShadow: '0 0 30rpx rgba(255, 217, 61, 0.8)', offset: 0.5 },
          { boxShadow: '0 0 0 rgba(255, 217, 61, 0)', offset: 1 }
        ],
        options: {
          duration: 1500,
          easing: 'ease-in-out',
          iterations: Infinity
        },
        emotion: 'happy',
        intensity: 'low'
      }
    ],
    sad: [
      {
        name: 'droop-sad',
        keyframes: [
          { transform: 'translateY(0) scale(1)', opacity: 1, offset: 0 },
          { transform: 'translateY(10rpx) scale(0.95)', opacity: 0.8, offset: 1 }
        ],
        options: {
          duration: 1000,
          easing: 'ease-out',
          fillMode: 'forwards'
        },
        emotion: 'sad',
        intensity: 'medium'
      },
      {
        name: 'tear-drop',
        keyframes: [
          { transform: 'translateY(-20rpx)', opacity: 0, offset: 0 },
          { transform: 'translateY(0)', opacity: 1, offset: 0.3 },
          { transform: 'translateY(100rpx)', opacity: 0, offset: 1 }
        ],
        options: {
          duration: 2000,
          easing: 'cubic-bezier(0.25, 0.46, 0.45, 0.94)',
          iterations: Infinity,
          delay: Math.random() * 3000
        },
        emotion: 'sad',
        intensity: 'high'
      },
      {
        name: 'fade-melancholy',
        keyframes: [
          { opacity: 1, filter: 'brightness(1)', offset: 0 },
          { opacity: 0.6, filter: 'brightness(0.7)', offset: 0.5 },
          { opacity: 1, filter: 'brightness(1)', offset: 1 }
        ],
        options: {
          duration: 3000,
          easing: 'ease-in-out',
          iterations: Infinity
        },
        emotion: 'sad',
        intensity: 'low'
      }
    ],
    angry: [
      {
        name: 'shake-anger',
        keyframes: [
          { transform: 'translateX(0)', offset: 0 },
          { transform: 'translateX(-10rpx)', offset: 0.1 },
          { transform: 'translateX(10rpx)', offset: 0.2 },
          { transform: 'translateX(-10rpx)', offset: 0.3 },
          { transform: 'translateX(10rpx)', offset: 0.4 },
          { transform: 'translateX(-10rpx)', offset: 0.5 },
          { transform: 'translateX(10rpx)', offset: 0.6 },
          { transform: 'translateX(-10rpx)', offset: 0.7 },
          { transform: 'translateX(10rpx)', offset: 0.8 },
          { transform: 'translateX(0)', offset: 1 }
        ],
        options: {
          duration: 500,
          easing: 'ease-in-out',
          iterations: 1
        },
        emotion: 'angry',
        intensity: 'high'
      },
      {
        name: 'pulse-rage',
        keyframes: [
          { transform: 'scale(1)', backgroundColor: 'var(--primary)', offset: 0 },
          { transform: 'scale(1.1)', backgroundColor: '#ff4444', offset: 0.5 },
          { transform: 'scale(1)', backgroundColor: 'var(--primary)', offset: 1 }
        ],
        options: {
          duration: 600,
          easing: 'ease-in-out',
          iterations: 3
        },
        emotion: 'angry',
        intensity: 'medium'
      },
      {
        name: 'heat-wave',
        keyframes: [
          { filter: 'hue-rotate(0deg) brightness(1)', offset: 0 },
          { filter: 'hue-rotate(20deg) brightness(1.2)', offset: 0.5 },
          { filter: 'hue-rotate(0deg) brightness(1)', offset: 1 }
        ],
        options: {
          duration: 800,
          easing: 'ease-in-out',
          iterations: Infinity
        },
        emotion: 'angry',
        intensity: 'low'
      }
    ],
    love: [
      {
        name: 'heartbeat',
        keyframes: [
          { transform: 'scale(1)', offset: 0 },
          { transform: 'scale(1.1)', offset: 0.14 },
          { transform: 'scale(1)', offset: 0.28 },
          { transform: 'scale(1.1)', offset: 0.42 },
          { transform: 'scale(1)', offset: 0.70 }
        ],
        options: {
          duration: 1500,
          easing: 'ease-in-out',
          iterations: Infinity
        },
        emotion: 'love',
        intensity: 'medium'
      },
      {
        name: 'love-glow',
        keyframes: [
          { boxShadow: '0 0 0 rgba(233, 30, 99, 0)', transform: 'scale(1)', offset: 0 },
          { boxShadow: '0 0 40rpx rgba(233, 30, 99, 0.8)', transform: 'scale(1.05)', offset: 0.5 },
          { boxShadow: '0 0 0 rgba(233, 30, 99, 0)', transform: 'scale(1)', offset: 1 }
        ],
        options: {
          duration: 2000,
          easing: 'ease-in-out',
          iterations: Infinity
        },
        emotion: 'love',
        intensity: 'high'
      },
      {
        name: 'float-romance',
        keyframes: [
          { transform: 'translateY(0)', offset: 0 },
          { transform: 'translateY(-10rpx)', offset: 0.5 },
          { transform: 'translateY(0)', offset: 1 }
        ],
        options: {
          duration: 3000,
          easing: 'ease-in-out',
          iterations: Infinity
        },
        emotion: 'love',
        intensity: 'low'
      }
    ],
    excited: [
      {
        name: 'bounce-excitement',
        keyframes: [
          { transform: 'translateY(0)', offset: 0 },
          { transform: 'translateY(-30rpx)', offset: 0.3 },
          { transform: 'translateY(0)', offset: 0.5 },
          { transform: 'translateY(-15rpx)', offset: 0.7 },
          { transform: 'translateY(0)', offset: 1 }
        ],
        options: {
          duration: 600,
          easing: 'cubic-bezier(0.68, -0.55, 0.265, 1.55)',
          iterations: Infinity
        },
        emotion: 'excited',
        intensity: 'high'
      },
      {
        name: 'sparkle-energy',
        keyframes: [
          { transform: 'rotate(0deg) scale(1)', opacity: 1, offset: 0 },
          { transform: 'rotate(180deg) scale(1.2)', opacity: 0.8, offset: 0.5 },
          { transform: 'rotate(360deg) scale(1)', opacity: 1, offset: 1 }
        ],
        options: {
          duration: 1000,
          easing: 'ease-in-out',
          iterations: Infinity
        },
        emotion: 'excited',
        intensity: 'medium'
      },
      {
        name: 'vibrate-enthusiasm',
        keyframes: [
          { transform: 'translateX(0)', offset: 0 },
          { transform: 'translateX(2rpx)', offset: 0.25 },
          { transform: 'translateX(-2rpx)', offset: 0.75 },
          { transform: 'translateX(0)', offset: 1 }
        ],
        options: {
          duration: 100,
          easing: 'linear',
          iterations: Infinity
        },
        emotion: 'excited',
        intensity: 'low'
      }
    ],
    calm: [
      {
        name: 'breathe-calm',
        keyframes: [
          { transform: 'scale(1)', opacity: 1, offset: 0 },
          { transform: 'scale(1.05)', opacity: 0.8, offset: 0.5 },
          { transform: 'scale(1)', opacity: 1, offset: 1 }
        ],
        options: {
          duration: 4000,
          easing: 'ease-in-out',
          iterations: Infinity
        },
        emotion: 'calm',
        intensity: 'low'
      },
      {
        name: 'wave-serenity',
        keyframes: [
          { transform: 'translateY(0) rotate(0deg)', offset: 0 },
          { transform: 'translateY(-5rpx) rotate(1deg)', offset: 0.25 },
          { transform: 'translateY(0) rotate(0deg)', offset: 0.5 },
          { transform: 'translateY(5rpx) rotate(-1deg)', offset: 0.75 },
          { transform: 'translateY(0) rotate(0deg)', offset: 1 }
        ],
        options: {
          duration: 6000,
          easing: 'ease-in-out',
          iterations: Infinity
        },
        emotion: 'calm',
        intensity: 'medium'
      },
      {
        name: 'ripple-peace',
        keyframes: [
          { boxShadow: '0 0 0 0 rgba(78, 205, 196, 0.4)', offset: 0 },
          { boxShadow: '0 0 0 20rpx rgba(78, 205, 196, 0)', offset: 1 }
        ],
        options: {
          duration: 2000,
          easing: 'ease-out',
          iterations: Infinity
        },
        emotion: 'calm',
        intensity: 'high'
      }
    ]
  };

  // 粒子效果配置
  particleConfigs = {
    happy: {
      count: 20,
      size: { min: 4, max: 8 },
      speed: { min: 50, max: 150 },
      color: ['#ffd93d', '#ff6b9d', '#4ecdc4'],
      shape: 'circle',
      lifetime: 3000,
      gravity: 0.1,
      wind: 0.05
    },
    love: {
      count: 15,
      size: { min: 6, max: 12 },
      speed: { min: 30, max: 100 },
      color: ['#e91e63', '#ff6b9d', '#f093fb'],
      shape: 'heart',
      lifetime: 4000,
      gravity: 0.05,
      wind: 0.02
    },
    excited: {
      count: 30,
      size: { min: 3, max: 6 },
      speed: { min: 100, max: 200 },
      color: ['#ff9800', '#ff6b6b', '#4ecdc4'],
      shape: 'sparkle',
      lifetime: 2000,
      gravity: 0.2,
      wind: 0.1
    },
    calm: {
      count: 10,
      size: { min: 8, max: 16 },
      speed: { min: 20, max: 60 },
      color: ['#4ecdc4', '#44a08d', '#093637'],
      shape: 'circle',
      lifetime: 5000,
      gravity: 0.02,
      wind: 0.01
    },
    sad: {
      count: 8,
      size: { min: 4, max: 10 },
      speed: { min: 10, max: 40 },
      color: ['#64b5f6', '#42a5f5', '#1976d2'],
      shape: 'circle',
      lifetime: 6000,
      gravity: 0.3,
      wind: 0
    }
  };

  /**
   * 播放情感动画
   */
  playEmotionAnimation(
    element,
    emotion,
    intensity = 'medium',
    options
  ) {
    return new Promise((resolve, reject) => {
      try {
        const animations = this.emotionAnimations[emotion];
        if (!animations) {
          reject(new Error(`未找到情感 ${emotion} 的动画`));
          return;
        }

        const targetAnimations = animations.filter(anim => anim.intensity === intensity);
        if (targetAnimations.length === 0) {
          reject(new Error(`未找到情感 ${emotion} 强度 ${intensity} 的动画`));
          return;
        }

        const animation = targetAnimations[Math.floor(Math.random() * targetAnimations.length)];
        const animationId = this.generateAnimationId();
        
        this.activeAnimations.add(animationId);
        
        // 在小程序中，我们需要通过其他方式实现动画
        this.executeWxAnimation(element, animation, options)
          .then(() => {
            this.activeAnimations.delete(animationId);
            resolve();
          })
          .catch((error) => {
            this.activeAnimations.delete(animationId);
            reject(error);
          });
        
      } catch (error) {
        reject(error);
      }
    });
  }

  /**
   * 执行微信小程序动画
   */
  executeWxAnimation(
    element,
    animation,
    options
  ) {
    return new Promise((resolve, reject) => {
      try {
        // 创建动画实例
        const animationInstance = wx.createAnimation({
          duration: options?.duration || animation.options.duration || 1000,
          timingFunction: options?.easing || animation.options.easing || 'ease',
          delay: options?.delay || animation.options.delay || 0,
          transformOrigin: '50% 50%'
        });

        // 应用关键帧动画
        this.applyKeyframes(animationInstance, animation.keyframes);
        
        // 获取动画数据
        const animationData = animationInstance.export();
        
        // 应用到元素
        if (typeof element === 'string') {
          // 通过页面setData应用动画
          const pages = getCurrentPages();
          if (pages.length > 0) {
            const currentPage = pages[pages.length - 1];
            if (currentPage.setData) {
              const animationKey = `${element}Animation`;
              currentPage.setData({
                [animationKey]: animationData
              });
              
              // 动画完成后清理
              setTimeout(() => {
                currentPage.setData({
                  [animationKey]: null
                });
                resolve();
              }, (options?.duration || animation.options.duration || 1000) + (options?.delay || animation.options.delay || 0));
            } else {
              reject(new Error('无法获取页面实例'));
            }
          } else {
            reject(new Error('无法获取当前页面'));
          }
        } else {
          reject(new Error('小程序环境不支持直接操作DOM元素'));
        }
        
      } catch (error) {
        reject(error);
      }
    });
  }

  /**
   * 应用关键帧到动画实例
   */
  applyKeyframes(animationInstance, keyframes) {
    keyframes.forEach((frame, index) => {
      // 解析变换
      if (frame.transform) {
        this.parseTransform(animationInstance, frame.transform);
      }
      
      // 解析透明度
      if (frame.opacity !== undefined) {
        animationInstance.opacity(frame.opacity);
      }
      
      // 如果不是最后一帧，添加step
      if (index < keyframes.length - 1) {
        animationInstance.step();
      }
    });
  }

  /**
   * 解析transform属性
   */
  parseTransform(animationInstance, transform) {
    // 解析translateX
    const translateXMatch = transform.match(/translateX\(([^)]+)\)/);
    if (translateXMatch) {
      const value = parseFloat(translateXMatch[1]);
      animationInstance.translateX(value);
    }
    
    // 解析translateY
    const translateYMatch = transform.match(/translateY\(([^)]+)\)/);
    if (translateYMatch) {
      const value = parseFloat(translateYMatch[1]);
      animationInstance.translateY(value);
    }
    
    // 解析scale
    const scaleMatch = transform.match(/scale\(([^)]+)\)/);
    if (scaleMatch) {
      const value = parseFloat(scaleMatch[1]);
      animationInstance.scale(value, value);
    }
    
    // 解析rotate
    const rotateMatch = transform.match(/rotate\(([^)]+)\)/);
    if (rotateMatch) {
      const value = parseFloat(rotateMatch[1]);
      animationInstance.rotate(value);
    }
  }

  /**
   * 创建粒子效果
   */
  createParticleEffect(
    containerId,
    emotion,
    duration = 5000
  ) {
    const config = this.particleConfigs[emotion];
    if (!config) {
      console.warn(`未找到情感 ${emotion} 的粒子配置`);
      return '';
    }

    const particleId = this.generateAnimationId();
    
    // 在小程序中，我们需要通过数据驱动的方式创建粒子
    const particles = this.generateParticleData(config);
    
    // 通过页面setData更新粒子数据
    const pages = getCurrentPages();
    if (pages.length > 0) {
      const currentPage = pages[pages.length - 1];
      if (currentPage.setData) {
        currentPage.setData({
          [`${containerId}Particles`]: particles
        });
        
        // 定时清理粒子
        setTimeout(() => {
          currentPage.setData({
            [`${containerId}Particles`]: []
          });
          this.particleSystems.delete(particleId);
        }, duration);
      }
    }
    
    this.particleSystems.set(particleId, {
      containerId,
      emotion,
      config,
      startTime: Date.now()
    });
    
    return particleId;
  }

  /**
   * 生成粒子数据
   */
  generateParticleData(config) {
    const particles = [];
    
    for (let i = 0; i < config.count; i++) {
      const particle = {
        id: `particle_${i}`,
        x: Math.random() * 100, // 百分比位置
        y: Math.random() * 100,
        size: Math.random() * (config.size.max - config.size.min) + config.size.min,
        color: config.color[Math.floor(Math.random() * config.color.length)],
        speed: Math.random() * (config.speed.max - config.speed.min) + config.speed.min,
        direction: Math.random() * 360,
        opacity: Math.random() * 0.8 + 0.2,
        shape: config.shape,
        animationDelay: Math.random() * 2000
      };
      particles.push(particle);
    }
    
    return particles;
  }

  /**
   * 停止动画
   */
  stopAnimation(animationId) {
    if (this.activeAnimations.has(animationId)) {
      this.activeAnimations.delete(animationId);
    }
    
    if (this.animationInstances.has(animationId)) {
      const instance = this.animationInstances.get(animationId);
      if (instance && instance.cancel) {
        instance.cancel();
      }
      this.animationInstances.delete(animationId);
    }
  }

  /**
   * 停止粒子效果
   */
  stopParticleEffect(particleId) {
    if (this.particleSystems.has(particleId)) {
      const system = this.particleSystems.get(particleId);
      
      // 清理页面数据
      const pages = getCurrentPages();
      if (pages.length > 0) {
        const currentPage = pages[pages.length - 1];
        if (currentPage.setData) {
          currentPage.setData({
            [`${system.containerId}Particles`]: []
          });
        }
      }
      
      this.particleSystems.delete(particleId);
    }
  }

  /**
   * 停止所有动画
   */
  stopAllAnimations() {
    this.activeAnimations.forEach(id => this.stopAnimation(id));
    this.particleSystems.forEach((_, id) => this.stopParticleEffect(id));
  }

  /**
   * 创建组合动画
   */
  createComboAnimation(
    elements,
    emotion,
    sequence = false
  ) {
    const promises = elements.map((element, index) => {
      const delay = sequence ? index * 200 : 0;
      return this.playEmotionAnimation(element, emotion, 'medium', { delay });
    });
    
    return Promise.all(promises);
  }

  /**
   * 创建交互反馈动画
   */
  createInteractionFeedback(
    element,
    type
  ) {
    const feedbackAnimations = {
      tap: {
        keyframes: [
          { transform: 'scale(1)', offset: 0 },
          { transform: 'scale(0.95)', offset: 0.5 },
          { transform: 'scale(1)', offset: 1 }
        ],
        options: { duration: 150, easing: 'ease-out' }
      },
      longpress: {
        keyframes: [
          { transform: 'scale(1)', opacity: 1, offset: 0 },
          { transform: 'scale(1.1)', opacity: 0.8, offset: 1 }
        ],
        options: { duration: 500, easing: 'ease-in-out' }
      },
      hover: {
        keyframes: [
          { transform: 'translateY(0)', offset: 0 },
          { transform: 'translateY(-4rpx)', offset: 1 }
        ],
        options: { duration: 200, easing: 'ease-out' }
      },
      focus: {
        keyframes: [
          { boxShadow: '0 0 0 rgba(102, 126, 234, 0)', offset: 0 },
          { boxShadow: '0 0 0 4rpx rgba(102, 126, 234, 0.3)', offset: 1 }
        ],
        options: { duration: 200, easing: 'ease-out' }
      }
    };
    
    const animation = feedbackAnimations[type];
    if (!animation) {
      return Promise.reject(new Error(`未知的交互类型: ${type}`));
    }
    
    return this.executeWxAnimation(element, {
      name: `feedback-${type}`,
      keyframes: animation.keyframes,
      options: animation.options,
      emotion: 'neutral',
      intensity: 'medium'
    });
  }

  /**
   * 获取情感动画列表
   */
  getEmotionAnimations(emotion) {
    return this.emotionAnimations[emotion] || [];
  }

  /**
   * 注册自定义动画
   */
  registerAnimation(emotion, animation) {
    if (!this.emotionAnimations[emotion]) {
      this.emotionAnimations[emotion] = [];
    }
    this.emotionAnimations[emotion].push(animation);
  }

  /**
   * 注册自定义粒子配置
   */
  registerParticleConfig(emotion, config) {
    this.particleConfigs[emotion] = config;
  }

  /**
   * 生成动画ID
   */
  generateAnimationId() {
    return `anim_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
  }

  /**
   * 获取活跃动画数量
   */
  getActiveAnimationCount() {
    return this.activeAnimations.size + this.particleSystems.size;
  }

  /**
   * 清理资源
   */
  cleanup() {
    this.stopAllAnimations();
    this.animationInstances.clear();
    this.particleSystems.clear();
    this.activeAnimations.clear();
  }
}

// 创建全局实例
const emotionAnimations = new EmotionAnimations();

export default emotionAnimations;
export { EmotionAnimations };